package com.example.demo11;

/**
 * UsernamePasswordAuthenticationFilter 过滤器，在这个过滤器之前，还有一个过滤器就是 SecurityContextPersistenceFilter
 *
 * 1. 在 doFilter 方法中，它首先会从 repo 中读取一个 SecurityContext 出来，这里的 repo 实际上就是 HttpSessionSecurityContextRepository，
 * 读取 SecurityContext 的操作会进入到 readSecurityContextFromSession 方法中，
 * 在这里我们看到了读取的核心方法 Object contextFromSession = httpSession.getAttribute(this.springSecurityContextKey);，
 * 这里的 springSecurityContextKey 对象的值就是 SPRING_SECURITY_CONTEXT，读取出来的对象最终会被转为一个 SecurityContext 对象。
 *
 * 2. SecurityContext 是一个接口，它有一个唯一的实现类 SecurityContextImpl，这个实现类其实就是用户信息在 session 中保存的 value。
 *
 * 3. 在拿到 SecurityContext 之后，通过 SecurityContextHolder.setContext 方法将这个 SecurityContext 设置到 ThreadLocal 中去，
 * 这样，在当前请求中，Spring Security 的后续操作，我们都可以直接从 SecurityContextHolder 中获取到用户信息了。
 *
 * 4. 接下来，通过 chain.doFilter 让请求继续向下走（这个时候就会进入到 UsernamePasswordAuthenticationFilter 过滤器中了）。
 *
 * 5. 在过滤器链走完之后，数据响应给前端之后，finally 中还有一步收尾操作，这一步很关键。
 * 这里从 SecurityContextHolder 中获取到 SecurityContext，获取到之后，会把 SecurityContextHolder 清空，
 * 然后调用 repo.saveContext 方法将获取到的 SecurityContext 存入 session 中。
 *
 * 每一个请求到达服务端的时候，首先从 session 中找出来 SecurityContext ，然后设置到 SecurityContextHolder 中去，方便后续使用，
 * 当这个请求离开的时候，SecurityContextHolder 会被清空，SecurityContext 会被放回 session 中，方便下一个请求来的时候获取。
 *
 */
public class SecurityContextPersistenceFilterGuide {
}
